package com.iltgcl.echovoicedemo.ui.main

import android.app.Application
import android.graphics.Color
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan
import androidx.hilt.lifecycle.ViewModelInject
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import com.github.musichin.reactivelivedata.ReactiveLiveData
import com.iltgcl.echovoice.client.IEchoVoice
import com.iltgcl.echovoicedemo.data.SettingsRepository
import com.iltgcl.echovoicedemo.speaker.IEchoSpeaker
import com.iltgcl.echovoicedemo.speaker.RangeStartInfo
import com.iltgcl.echovoicedemo.speaker.SpeakerManager
import com.iltgcl.echovoicedemo.ui.base.BaseViewModel
import timber.log.Timber

class MainViewModel @ViewModelInject constructor (
    application: Application,
    private val speakerManager: SpeakerManager,
    private val settingsRepository: SettingsRepository) : BaseViewModel(application){

    val initialize:LiveData<Boolean> = speakerManager.initialize
    private val mediaSpeakerState:LiveData<Int> = Transformations.switchMap(initialize) {
        if (it) {
            speakerManager.getSpeakerState(IEchoVoice.USAGE_MEDIA)
        } else {
            null
        }
    }

    private val _mediaRangeStart:LiveData<RangeStartInfo> = Transformations.switchMap(initialize) {
        if (it) {
            speakerManager.getRangeStart(IEchoVoice.USAGE_MEDIA)
        } else {
            null
        }
    }

    private val navSpeakerState:LiveData<Int> = Transformations.switchMap(initialize) {
        if (it) {
            speakerManager.getSpeakerState(IEchoVoice.USAGE_NOTIFICATION)
        } else {
            null
        }
    }

    val mediaCanStop: LiveData<Boolean> = Transformations.map(mediaSpeakerState) {
        it != null && it != IEchoSpeaker.STATE_STOP
    }

    val mediaCanPause:LiveData<Boolean> = Transformations.map(mediaSpeakerState) {
        it != null && it == IEchoSpeaker.STATE_SPEAKING
    }

    val mediaCanResume:LiveData<Boolean> = Transformations.map(mediaSpeakerState) {
        it != null && it == IEchoSpeaker.STATE_PAUSE
    }

    private val _novelText = MutableLiveData<CharSequence>()

    val novelText: LiveData<CharSequence> = ReactiveLiveData.combineLatest(_novelText, _mediaRangeStart) { text, rangeStart->
        val builder = SpannableStringBuilder(text)
        builder.clearSpans()
        if (rangeStart.start != rangeStart.end) {
            Timber.d("[ForegroundColorSpan]start:${rangeStart.start}, end:${rangeStart.end}")
            val colorSpan = ForegroundColorSpan(Color.RED)
            builder.setSpan(colorSpan, rangeStart.start, rangeStart.end, Spannable.SPAN_INCLUSIVE_INCLUSIVE)
        }
        builder
    }

    val navCanStop: LiveData<Boolean> = Transformations.map(navSpeakerState) {
        it != null && it != IEchoSpeaker.STATE_STOP
    }

    val navText = MutableLiveData<String>()

    private var clickCount = 0

    fun start() {
        _novelText.value = sampleText
        navText.value = sampleNavText
    }

    fun speakNovel() {
        clickCount++
        val voiceName = settingsRepository.getVoiceName()
        val speechRate = settingsRepository.getSpeechRate()
        val volume = settingsRepository.getVolume()
        val pitch = settingsRepository.getPitch()
        Timber.d("[speakNovel]voicer:$voiceName, rate:$speechRate, volume:$volume, pitch:$pitch")
        speakerManager.speak(IEchoVoice.USAGE_MEDIA,
            novelText.value!!,
            "EchoSampleTxt$clickCount",
            settingsRepository.getVoiceName(),
            settingsRepository.getSpeechRate(),
            settingsRepository.getVolume(),
            settingsRepository.getPitch())

    }

    fun stopNovel() {
        Timber.d("[stopNovel]=====")
        speakerManager.stop(IEchoVoice.USAGE_MEDIA)
    }

    fun pauseNovel() {
        Timber.d("[pauseNovel]=====")
        speakerManager.pause(IEchoVoice.USAGE_MEDIA)
    }

    fun resumeNovel() {
        Timber.d("[resumeNovel]=====")
        speakerManager.resume(IEchoVoice.USAGE_MEDIA)
    }

    fun speakNav() {
        clickCount++
        val voiceName = settingsRepository.getVoiceName()
        val speechRate = settingsRepository.getSpeechRate()
        val volume = settingsRepository.getVolume()
        val pitch = settingsRepository.getPitch()
        Timber.d("[speakNavigation]voicer:$voiceName, rate:$speechRate, volume:$volume, pitch:$pitch")
        speakerManager.speak(IEchoVoice.USAGE_NOTIFICATION,
                navText.value!!,
                "EchoSampleTxt$clickCount",
                settingsRepository.getVoiceName(),
                settingsRepository.getSpeechRate(),
                settingsRepository.getVolume(),
                settingsRepository.getPitch())
    }

    fun stopNav() {
        speakerManager.stop(IEchoVoice.USAGE_NOTIFICATION)
    }

    companion object {
        val sampleText = """
天地不仁，以万物为刍狗！

这世间本是没有什么神仙的，但自太古以来，人类眼见周遭世界，诸般奇异之事，电闪雷鸣，又有天灾人祸，伤亡无数，哀鸿遍野，决非人力所能为，所能抵挡。遂以为九天之上，有诸般神灵，九幽之下，亦是阴魂归处，阎罗殿堂。

于是神仙之说，流传于世。无数人类子民，诚心叩拜，向着自己臆想创造出的各种神明顶礼膜拜，祈福诉苦，香火鼎盛。

自古以来，凡人无不有一死。但世人皆恶死爱生，更有地府阎罗之说，平添了几分苦惧，在此之下，遂有长生不死之说。

相比与其他生灵物种，人类或在体质上处于劣势，但万物灵长，却是绝无虚言。在追求长生的原动力下，一代代聪明才智之士，前赴后继，投入毕生精力，苦苦钻研。至今为止，虽然真正意义上的长生不死仍未找到，却有一些修真炼道之士，参透些天地造化，以凡人之身，掌握强横力量，借助各般秘宝法器之力，竟可震撼天地，有雷霆之威。而一些得到高深的前辈，更传说已活上千年之久而不死。世上之人以为得道成仙，便有更多人投入修真炼道之路。

神州浩土，广瀚无边。唯有中原大地，最是丰美肥沃，天下人口十之八九聚居于此。而东南西北边荒之地，山险水恶，多凶兽猛禽，多恶瘴毒物，亦多蛮族夷民，虏毛饮血，是以人迹罕至。而人间自古相传，有洪荒遗种，残存人世，藏于深山密谷，寿逾万年，却是无人得见。

时至今日，人间修真炼道之人，多如过江之鲫，数不胜数。又以神州浩土之广阔，人间奇人异士之多，故修炼之法道林林总总，俱不相同。长生之法还未找到，彼此间却逐渐有了门派之分，正邪之别。由之而起的门户之见，勾心斗角乃至争伐杀戮，在所多有。

当长生不死看起来那般遥远而不可捉摸，修炼中所带来的力量，便逐渐成了许多人的目标。

方今之世，正道大昌，邪魔退避。中原大地山灵水秀，人气鼎盛，物产丰富，为正派诸家牢牢占据。其中尤以“青云门”、“天音寺”、和“焚香谷”为三大支柱，是为领袖。

这个故事，便是从“青云门”开始的。
                """.trimIndent()

        val sampleNavText = """
            前方300米处有违章拍照，请谨慎驾驶。
        """.trimIndent()
    }
}

